#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

static const std::string sep = "\r\n";  //添加报头
static const std::string protsep = " "; //自定义时用的

//条件编译：定义时使用Jsoncpp库，没定义时使用自定义
//#define SELF

//添加报头
//3\r\n45'+'\r\n
void AddHeader(std::string* out)
{   
    int len = out->size();  //获取长度
    *out = std::to_string(len) + sep + *out + sep;  //进行拼接
}


//提取一个完整的报文出来
bool SplitMessage(std::string &in,std::string *out)
{
    //进行字符串操作提取一个完整报文
    auto pos = in.find(sep);
    if(pos == std::string::npos)
    {
        return false;
    }

    int len = std::stoi(in.substr(0,pos));
    int mlen = len + pos +(sep.size()*2);

    if(in.size() < mlen)
    {
        return false;
    }

    *out = in.substr(pos+2,len);   

    in.erase(0,mlen);   //删除提取出来的完整报文
    return true;
}


// 请求
class Request
{
public:
    Request(int x = 0, int y = 0, int oper = 0)
        : _x(x),
          _y(y),
          _oper(oper)
    {
    }

    // 序列化
    bool Serialize(std::string *out)
    {
#ifdef SELF
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        *out = root.toStyledString();

        return true;
#else
        //拼接  1 + 2
        *out = std::to_string(_x) + protsep + _oper + protsep + std::to_string(_y); 
        return true;
#endif
    }

    // 反序列化
    bool Deserialization(const std::string &in)
    {
#ifdef SELF
        Json::Reader reader;
        Json::Value root;

        bool parsingSuccessful = reader.parse(in,root);
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();
        return true;
#else
        //进行字符串操作完成反序列化
        int pos = in.find(protsep);
        int rpos = in.rfind(protsep);
        if(pos == std::string::npos || rpos == std::string::npos)
            return false;

        std::string str_x = in.substr(0,pos);
        std::string str_y = in.substr(rpos+1);
        if(str_x.empty() || str_y.empty())
            return false;
        
        _x = std::stoi(str_x);
        _y = std::stoi(str_y);
        _oper = in[pos+1];
        return true;
#endif
    }

    //获取成员变量
    int GetX() const { return _x; }
    int GetY() const{ return _y; } 
    int GetOper() const{ return _oper; } 
    ~Request() = default;

private:
    int _x; //第一个操作数
    int _y; //第二个操作数
    char _oper; //操作符
};

// 应答
class Response
{
public:
    Response(int res = 0,int code = 0)
    :_res(res),
    _code(code)
    {}

    // 序列化
    bool Serialize(std::string *out)
    { 
#ifdef SELF
        Json::Value root;
        root["res"] = _res;
        root["code"] = _code; 
        *out = root.toStyledString();

        return true;
#else
        //拼接
        *out =std::to_string(_res) + protsep + std::to_string(_code);
        return true;
#endif 
    }

    // 反序列化
    bool Deserialization(const std::string &in)
    {
#ifdef SELF
        Json::Reader reader;
        Json::Value root;

        bool parsingSuccessful = reader.parse(in,root);
        _res = root["res"].asInt();
        _code = root["code"].asInt();
        return true;
#else
        //通过字符串操作完成反序列化
        int pos = in.find(protsep);
        if(pos == std::string::npos)
            return false;

        _res = std::stoi(in.substr(0,pos));
        _code = std::stoi(in.substr(pos+1));

        return true;

#endif
    }

    //获取成员变量
    int GetRes(){return _res;}
    int GetCode(){return _code;}

    ~Response() = default;
private:
    int _res;   //结果
    int _code;  //返回码
};